/**
 * 
 */
package cz.cuni.mff.abacs.burglar.visual;

import org.newdawn.slick.GameContainer;
import org.newdawn.slick.Graphics;
import org.newdawn.slick.Image;
import org.newdawn.slick.SlickException;
import org.newdawn.slick.Sound;
import org.newdawn.slick.geom.Rectangle;
import org.newdawn.slick.state.BasicGameState;
import org.newdawn.slick.state.StateBasedGame;

import com.aem.sticky.StickyListener;
import com.aem.sticky.button.SimpleButton;
import com.aem.sticky.button.events.ButtonListener;
import com.aem.sticky.button.events.ClickListener;


/** 
 * Game main menu implementation
 * 
 * @author abacs
 *
 */
public class MenuState extends BasicGameState {
	
	protected float SCALE_STEP = 0.0001f;
	protected float MIN_SCALE  = 1.0000f;
	protected float MAX_SCALE  = 1.0500f;
	
	// -------------------------------------------------------------------------
	
	private final int _stateID;
	
	protected StickyListener _buttonListener;
	protected SimpleButton _newGameButton;
	protected SimpleButton _levelSelectButton;
	protected SimpleButton _exitButton;
	
	protected GameContainer _container = null;
	protected StateBasedGame _stateBasedGame = null;
	
	
	// -------------------------------------------------------------------------
	// constructors:
	
	
	/** 
	 * 
	 * 
	 * @param stateId
	 */
	public MenuState(int stateId) {
		this._stateID = stateId;
	}
	
	
	// -------------------------------------------------------------------------
	// BasigGameState:
	
	
	@Override
	public int getID() {
		return this._stateID;
	}
	
	
	/** 
	 * Initialize any needed data before the menu loop.
	 * 
	 * @param container 
	 * @param game 
	 * @throws SlickExpression
	 */
	@Override
	public void init(
			GameContainer container,
			StateBasedGame game
		) throws SlickException {
		
		this._stateBasedGame = game;
		this._container = container;
		
		Sound buttonSound = new Sound(Main.RESOURCE_PATH + "sound/click.ogg");
		
		// buttons:
		this._buttonListener = new StickyListener();
		container.getInput().addListener(this._buttonListener);
		
		this.createExitButton(container, buttonSound);
		this.createLevelSelectButton(container, buttonSound);
	}
	
	
	/**
	 * Called during the game to update the logic in our world,
	 * within this method we obtain the user input,
	 * calculate the world response to the input, do the calculation.
	 * 
	 * @param container
	 * @param game
	 * @param delta
	 * @throws SlickExpression
	 */
	@Override
	public void update(
			GameContainer container,
			StateBasedGame game,
			int delta
	) throws SlickException {
		this._exitButton.update(container, delta);
		this._levelSelectButton.update(container, delta);
	}

	
	/**
	 *  Allows to draw the menu.
	 *  
	 * @param container
	 * @param game
	 * @param delta
	 * @throws SlickExpression
	 */
	@Override
	public void render(
			GameContainer container,
			StateBasedGame game,
			Graphics graphics
	) throws SlickException {
		// Draw menu
		this._exitButton.render(container, graphics);
		this._levelSelectButton.render(container, graphics);
	}
	
	
	// -------------------------------------------------------------------------
	// buttons:
	
	
	/**
	 * 
	 * @param container
	 * @param buttonSound
	 * @throws SlickException
	 */
	protected void createLevelSelectButton(
			final GameContainer container,
			Sound buttonSound
	) throws SlickException {
		
		// load the menu images:
		Image menuOptions = 
			new Image(Main.RESOURCE_PATH + "img/menuoptions.png");
		Image startImg     = menuOptions.getSubImage(0, 142, 377, 71);
		Image startImgDark = menuOptions.getSubImage(0, 0, 377, 71);
		
		float x = container.getWidth() / 2 - 189;
		float y = container.getHeight() / 2 - 160;
		this._levelSelectButton = new SimpleButton(
				new Rectangle(x, y, 378, 71),
				startImgDark, startImg, buttonSound
		);

		this._buttonListener.add(this._levelSelectButton);
		
		this._levelSelectButton.addListener(new ClickListener() {
			
			@Override
			public void onClick(
					com.aem.sticky.button.Button arg0,
					float arg1,
					float arg2
			) {	
				// enters the new game state:
				_stateBasedGame.getState(Main.LEVEL_SELECT_STATE);
				_stateBasedGame.enterState(Main.LEVEL_SELECT_STATE);
			}
			
			/** Does nothing */
			@Override
			public void onDoubleClick(
					com.aem.sticky.button.Button arg0,
					float arg1,
					float arg2
			) {	}
			
			/** Does nothing */
			@Override
			public void onRightClick(
					com.aem.sticky.button.Button arg0,
					float arg1,
					float arg2
			) { }
		});
		
		this._levelSelectButton.addListener(new ButtonListener() {
			@Override
			public void onMouseEnter(com.aem.sticky.button.Button arg0) { }
			@Override
			public void onMouseExit(com.aem.sticky.button.Button arg0) { }
		});
	}
	
	
	/**
	 * 
	 * 
	 * @param container
	 * @param buttonSound
	 * @throws SlickException
	 */
	protected void createExitButton(
			GameContainer container,
			Sound buttonSound
	) throws SlickException {
		
		// load the menu images:
		Image menuOptions = 
			new Image(Main.RESOURCE_PATH + "img/menuoptions.png");
		Image exitImg     = menuOptions.getSubImage(238, 213, 139, 71);
		Image exitImgDark = menuOptions.getSubImage(238, 71, 139, 71);
		
		float x = container.getWidth() / 2 - 60;
		float y = container.getHeight() / 2 + 20;
		this._exitButton = new SimpleButton(
				new Rectangle(x, y, 120, 71),
				exitImgDark, exitImg, buttonSound
		);
		
		this._buttonListener.add(this._exitButton);
		
		this._exitButton.addListener(new ClickListener() {
			
			@Override
			public void onClick(
					com.aem.sticky.button.Button arg0,
					float arg1,
					float arg2
			) {	
				_container.exit();
			}

			@Override
			public void onDoubleClick(
					com.aem.sticky.button.Button arg0,
					float arg1,
					float arg2
			) { }
			
			@Override
			public void onRightClick(
					com.aem.sticky.button.Button arg0,
					float arg1,
					float arg2
			) { }
		});
		
		this._exitButton.addListener(new ButtonListener() {
			@Override
			public void onMouseEnter(com.aem.sticky.button.Button arg0) { }
			@Override
			public void onMouseExit(com.aem.sticky.button.Button arg0) { }
		});
		
		
	}
	
}
